package com.zhxy.util.publish;

import java.util.List;


/**
 * 向上级Publisher订阅后发布给下级Subscriber
 * 如果有多个下级Subscriber订阅了同一类型消息，则保证只向上级订阅一次
 * @author 刘勉
 *
 * @param <P>
 */
public abstract class PublisherRouter<P> extends AbstractPublisher<P> implements Publisher<P> {
	
	private Publisher<P> publisher;
	
	private LocalSubscriber localSubscriber = new LocalSubscriber();

	public void setPublisher(Publisher<P> publisher) {
		this.publisher = publisher;
	}

	@Override
	public synchronized void subscribe(Subscriber<P> subscriber, String name) throws SubscribeException {
		if (!containsName(name)) {
			publisher.subscribe(localSubscriber, name);
		}
		doSubscribe(subscriber, name);
	}

	@Override
	public synchronized void unsubscribe(Subscriber<P> subscriber, String name) throws SubscribeException {
		doUnsubscribe(subscriber, name);
		if (!containsName(name)) {
			publisher.unsubscribe(localSubscriber, name);
		}
	}
	
	@Override
	public synchronized void cleanSubscribe(Subscriber<P> subscriber) throws SubscribeException {
		List<String> names = namesBySubscriber(subscriber);
		doCleanSubscribe(subscriber);
		for (String name : names) {
			if (!containsName(name)) {
				publisher.unsubscribe(localSubscriber, name);
			}
		}
	}
	
	protected abstract void onMessage(String name, P publication);
	
	class LocalSubscriber implements Subscriber<P> {
		@Override
		public void feed(String name, P publication) {
			onMessage(name, publication);
		}
	}
}
